package nrd;

import static org.junit.Assert.assertTrue;
import robocode.control.events.BattleCompletedEvent;
import robocode.control.events.RoundStartedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.snapshot.IRobotSnapshot;
import robocode.control.testing.RobotTestBed;

/**
 * Verify that move2 from TheOrangeRobot works properly in all cases.
 * 
 * @author nathan
 * 
 */
public class TestTheOrangeRobotMove2 extends RobotTestBed {

  double xStart = 0;
  double yStart = 0;

  boolean moveType1 = false;

  boolean movement1 = false;
  boolean movement2 = false;

  double move2Distance = 0;
  int switchCounter = 1;

  /**
   * Specifies that Crazy and TheOrangeRobot are to be matched up in this test case.
   * 
   * @return The comma-delimited list of robots in this match.
   */
  @Override
  public String getRobotNames() {
    return "sample.Crazy,nrd.TheOrangeRobot";
  }

  /**
   * This test runs for 1 round.
   * 
   * @return The number of rounds.
   */
  @Override
  public int getNumRounds() {
    return 10;
  }

  /**
   * Determines whether code in move2 executes both possible ways. Move1 code is left since it will
   * eventually execute. Move1 is routine while move2 is reactionary.
   * 
   * @param event Info about the current state of the battle.
   */
  @Override
  public void onTurnEnded(TurnEndedEvent event) {
    IRobotSnapshot robot = event.getTurnSnapshot().getRobots()[1];
    double xPos = robot.getX();
    double yPos = robot.getY();

    double distance = -10;
    if (xPos >= xStart) {
      if (yPos >= yStart) {
        distance = Math.sqrt((Math.pow((xPos - xStart), 2)) + (Math.pow((yPos - yStart), 2)));
      }
      else {
        distance = Math.sqrt((Math.pow((xPos - xStart), 2)) + (Math.pow((yStart - yPos), 2)));
      }
    }
    else {
      if (yPos >= yStart) {
        distance = Math.sqrt((Math.pow((xStart - xPos), 2)) + (Math.pow((yPos - yStart), 2)));
      }
      else {
        distance = Math.sqrt((Math.pow((xStart - xPos), 2)) + (Math.pow((yStart - yPos), 2)));
      }
    }
    // error margin of 2.5 pixels
    if (Math.abs(75 - distance) <= 2.5) {
      moveType1 = true;
      xStart = xPos;
      yStart = yPos;
    }
    // move1 done
    // test if move2 works
    // error margin if 5 pixels
    if (switchCounter == 1 && !moveType1) {
      move2Distance = distance;
      switchCounter = 0;
      movement1 = true;
      moveType1 = false;
    }
    if (switchCounter == 0 && !moveType1) {
      if (Math.abs((distance * 2) - move2Distance) <= 5) {
        movement2 = true;
      }
      switchCounter = 1;
    }
    moveType1 = false;

  }

  /**
   * Gets the start position of the robot for distance calculations.
   * 
   * @param event details of the opening round
   */
  @Override
  public void onRoundStarted(RoundStartedEvent event) {
    IRobotSnapshot robot = event.getStartSnapshot().getRobots()[1];
    xStart = robot.getX();
    yStart = robot.getY();
  }

  /**
   * Reports results of the battle.
   * 
   * @param event Details about the completed battle.
   */
  @Override
  public void onBattleCompleted(BattleCompletedEvent event) {
    assertTrue("Robot Completes first type of movement in move2.", movement1);
    assertTrue("Robot Completes second type of movement in move2.", movement2);
  }
}
